/**
 * @file TcpConnection.hh
 * @author zziywang (zziywang@163.com)
 * @brief { life is too short to learn cpp! }
 * @version 1.0
 * @date 2022-05-07
 *
 * @copyright Copyright (c) 2022
 *
 */

#pragma once

#include "InetAddress.hh"
#include "Noncopyable.hh"
#include "Socket.hh"
#include "SocketIO.hh"
#include <functional>
#include <memory>

namespace snow
{
// v2新增
class TcpConnection; // 前向声明，告诉后面TcpConectionPtr这是个类，告诉enable_shared_from_this
using TcpConnectionPtr = std::shared_ptr<class TcpConnection>;
using TcpConnectionCallBack = std::function<void(const TcpConnectionPtr &)>;

class TcpConnection
    : Noncopyable,
    public std::enable_shared_from_this<class TcpConnection>
{
public:
    TcpConnection(int fd);
    ~TcpConnection();

    string recv();
    string recvLine();
    void send(const string &msg);

    void shutdown(); // 关闭写端

    string printTcp() const; // 打印TCP连接，四元组（本端ip,port,对端ip,port)
    InetAddress getLocalAddress() const;
    InetAddress getPeerAddress() const;

    // v2新增
    // 设置回调函数，传给tcp对象中的成员
    void setConnectionCallBack(const TcpConnectionCallBack &cb);
    void setMessageCallBack(const TcpConnectionCallBack &cb);
    void setCloseCallBack(const TcpConnectionCallBack &cb);
    // 执行回调函数
    void handleNewConnectionCallBack();
    void handleMessageCallBack();
    void handleCloseCallBack();

private:
    Socket sock_;
    InetAddress localAddr_;
    InetAddress peerAddr_;
    SocketIO sockio_;
    bool isShutdownWrite_; // 是否关闭本端的写端

    // EventLoop交给tcp执行的回调函数
    // 由set设置，handle调用
    TcpConnectionCallBack onConnection_;
    TcpConnectionCallBack onMessage_;
    TcpConnectionCallBack onClose_;
};

} // namespace snow